#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author:    御风
# @Mail:      zhong.yufeng@foxmail.com
# @Time:      2022/4/12 1:42


import base64
import config
import time
from flask import request, g, Response
from utils.session.serializer import Serializer
from utils.helper import strRandom

# 固定或随机
USE_RANDOM_KEY = True
SECRET_KEY = strRandom(64) if USE_RANDOM_KEY else config.SECRET_KEY
SECRET_SALT = strRandom(16) if USE_RANDOM_KEY else config.SECRET_SALT
SERIALIZER = Serializer(SECRET_KEY, SECRET_SALT)


class Session(object):
    key = "session"
    timeKey = "_session_time"
    timeMax = 60 * 60 * 24 * 15
    timeMaxLogin = 60 * 60 * 24 * 3

    @staticmethod
    def get():
        session = getattr(g, Session.key, None)
        try:
            if not isinstance(session, dict):
                data = request.args.get(Session.key, "", str)
                if data == "":
                    data = request.headers.get(Session.key, "", str)
                    if data == "":
                        data = request.cookies.get(Session.key, "", str)
                if data != "":
                    data += "=" * ((4 - len(data) % 4) % 4)
                    session = SERIALIZER.loads(base64.urlsafe_b64decode(data.encode("utf-8")).decode("utf-8"))
        except Exception:
            session = { }

        # session 有效时间
        # ts = int(time.time()) - int(session.get(Session.timeKey, 0))
        # if ts > Session.timeMax:
        #     session = { }

        return { } if not session else session

    @staticmethod
    def set(session: dict):
        g.session = None if not isinstance(session, dict) else session

    @staticmethod
    def serializer():
        session = Session.get()
        if not session:
            return None
        else:
            session[Session.timeKey] = int(time.time())
            return base64.urlsafe_b64encode(SERIALIZER.dumps(session).encode("utf-8")).decode("utf-8").strip("=")

    @staticmethod
    def clear(response: Response):
        if Session.key in request.cookies.keys():
            response.delete_cookie(Session.key)
        else:
            for header in response.headers:
                k, v = header[0], header[1]
                if k == "Set-Cookie" and isinstance(v, str):
                    carr = v.split(";")[0].split("=", maxsplit=1)
                    if Session.key == carr[0]:
                        response.delete_cookie(Session.key)
                        break

    @staticmethod
    def save(response: Response):
        data = Session.serializer()
        if not data:
            Session.clear(response)
        else:
            response.set_cookie(Session.key, data)
